package service

import (
	"context"
	"errors"
	"fmt"
	"time"
	__ "user_srv/basic/userproto"
	"user_srv/handler/dao"
	"user_srv/handler/models"
)

// 提现常量
const (
	MinWithdrawalAmount     = 100.0   // 最小提现金额
	MaxWithdrawalAmount     = 50000.0 // 最大提现金额
	DefaultWithdrawalStatus = 0       // 默认待审核状态
)

// 账户类型常量
const (
	AccountTypeBank   = 1 // 银行卡
	AccountTypeAlipay = 2 // 支付宝
	AccountTypeWeChat = 3 // 微信
)

// modelToProto 将models.Withdrawal转换为proto.WithdrawalInfo
func modelToProto(w *models.Withdrawal) *__.WithdrawalInfo {
	if w == nil {
		return nil
	}

	info := &__.WithdrawalInfo{
		Id:            w.ID,
		UserId:        w.UserID,
		WithdrawalNo:  w.WithdrawalNo,
		Amount:        w.Amount,
		AccountType:   int32(w.AccountType),
		AccountNumber: w.AccountNumber,
		AccountName:   w.AccountName,
		BankName:      w.BankName,
		Status:        int32(w.Status),
		RejectReason:  w.RejectReason,
		AuditorId:     w.AuditorID,
		Remark:        w.Remark,
		CreatedAt:     w.CreatedAt.Format(time.DateTime),
		UpdatedAt:     w.UpdatedAt.Format(time.DateTime),
	}

	if w.AuditTime != nil {
		info.AuditTime = w.AuditTime.Format(time.DateTime)
	}

	return info
}

// validateCreateWithdrawal 验证创建提现请求参数
func validateCreateWithdrawal(req *__.CreateWithdrawalReq) error {
	if req.Amount <= 0 {
		return errors.New("提现金额必须大于0")
	}
	if req.Amount < MinWithdrawalAmount {
		return fmt.Errorf("提现金额不能少于%.2f元", MinWithdrawalAmount)
	}
	if req.Amount > MaxWithdrawalAmount {
		return fmt.Errorf("单笔提现金额不能超过%.2f元", MaxWithdrawalAmount)
	}
	if req.AccountType < AccountTypeBank || req.AccountType > AccountTypeWeChat {
		return errors.New("收款账户类型无效")
	}
	if req.AccountNumber == "" {
		return errors.New("收款账号不能为空")
	}
	if req.AccountName == "" {
		return errors.New("收款人姓名不能为空")
	}
	return nil
}

// generateWithdrawalNo 生成提现单号
func generateWithdrawalNo(userID uint64) string {
	return fmt.Sprintf("WD%d%d", time.Now().Unix(), userID)
}

// validateAuditRequest 验证审核请求
func validateAuditRequest(req *__.AuditWithdrawalReq) error {
	if req.Status != 1 && req.Status != 2 {
		return errors.New("审核状态无效")
	}
	if req.Status == 2 && req.Reason == "" {
		return errors.New("拒绝提现必须填写拒绝原因")
	}
	return nil
}

// CreateWithdrawal 创建提现申请 (gRPC接口)
func (s *Server) CreateWithdrawal(ctx context.Context, req *__.CreateWithdrawalReq) (*__.CreateWithdrawalResp, error) {
	if err := validateCreateWithdrawal(req); err != nil {
		return nil, err
	}

	// 生成提现单号
	withdrawalNo := generateWithdrawalNo(req.UserId)

	withdrawal := &models.Withdrawal{
		UserID:        req.UserId,
		WithdrawalNo:  withdrawalNo,
		Amount:        req.Amount,
		AccountType:   int8(req.AccountType),
		AccountNumber: req.AccountNumber,
		AccountName:   req.AccountName,
		BankName:      req.BankName,
		Status:        DefaultWithdrawalStatus,
	}

	if err, _ := dao.CreateWithdrawal(withdrawal); err != nil {
		return nil, fmt.Errorf("创建提现申请失败: passenger %w", err)
	}

	return &__.CreateWithdrawalResp{
		Withdrawal: modelToProto(withdrawal),
	}, nil
}

// GetWithdrawalList 获取提现记录列表 (gRPC接口)
func (s *Server) GetWithdrawalList(ctx context.Context, req *__.GetWithdrawalListReq) (*__.GetWithdrawalListResp, error) {
	page, pageSize := normalizePagination(req.Page, req.PageSize)
	list, total, err := dao.GetUserWithdrawals(req.UserId, page, pageSize)
	if err != nil {
		return nil, err
	}

	resp := &__.GetWithdrawalListResp{
		Total: total,
	}

	for _, w := range list {
		resp.List = append(resp.List, modelToProto(w))
	}

	return resp, nil
}

// GetWithdrawalDetailG 获取提现详情 (gRPC接口)
func (s *Server) GetWithdrawalDetailG(ctx context.Context, req *__.GetWithdrawalDetailReq) (*__.GetWithdrawalDetailResp, error) {
	withdrawal, err := dao.GetWithdrawalByID(req.Id)
	if err != nil {
		return nil, err
	}

	return &__.GetWithdrawalDetailResp{
		Withdrawal: modelToProto(withdrawal),
	}, nil
}

// AuditWithdrawalG 审核提现申请 (gRPC接口)
func (s *Server) AuditWithdrawalG(ctx context.Context, req *__.AuditWithdrawalReq) (*__.AuditWithdrawalResp, error) {
	if err := validateAuditRequest(req); err != nil {
		return &__.AuditWithdrawalResp{
			Success: false,
			Message: err.Error(),
		}, nil
	}

	if err := dao.UpdateWithdrawalStatus(req.Id, int8(req.Status), req.AuditorId, req.Reason); err != nil {
		return &__.AuditWithdrawalResp{
			Success: false,
			Message: err.Error(),
		}, nil
	}

	return &__.AuditWithdrawalResp{
		Success: true,
		Message: "审核成功",
	}, nil
}

// SumWithdrawalAmount 提现金额聚合统计
func (s *Server) SumWithdrawalAmount(ctx context.Context, req *__.SumWithdrawalAmountReq) (*__.SumWithdrawalAmountResp, error) {
	if req == nil {
		return nil, errors.New("参数不能为空")
	}

	//参数验证
	groupType := int(req.Type)

	if groupType <= 0 {
		groupType = 1
	}
	//调用DAO层获取统计数据
	xAxis, yAxis, err := dao.SumWithdrawalAmount(req.StartTime, req.EndTime, groupType)
	if err != nil {
		return nil, fmt.Errorf("获取提现统计失败:%w", err)
	}
	resp := &__.SumWithdrawalAmountResp{
		XAxis: xAxis,
		YAxis: yAxis,
	}
	return resp, nil
}
